package com.ceair.flight.refund.service.cronjob.impl;

import com.ceair.flight.refund.dto.appmoblie.RefundApplyDto;
import com.ceair.flight.refund.dto.external.BasePageQueryReq;
import com.ceair.flight.refund.location.dt.enums.RefundStatus;
import com.ceair.flight.refund.service.cronjob.IScheduleService;
import com.ceair.flight.refund.service.external.IRefundQueryOperation;
import com.ceair.flight.refund.service.external.IRefundUpdateOperation;
import com.ceair.muservice.common.dto.page.PaginationResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author youguilin
 */
abstract class AbstractScheduleServiceImpl implements IScheduleService {

    private static final Logger LOG = LoggerFactory.getLogger(AbstractScheduleServiceImpl.class);
    @Autowired
    private IRefundQueryOperation refundQueryOperation;
    @Autowired
    private IRefundUpdateOperation refundUpdateOperation;
    private Integer batchSize = 20;

    @Override
    public void doScheduleTask() {
        LOG.info("Starting schedule job");
        BasePageQueryReq req = buildQueryReq();
        doScheduleTask(req);
        LOG.info("Finished schedule job");
    }

    protected void doScheduleTask(BasePageQueryReq pageQueryReq) {
        PaginationResult<RefundApplyDto> pageResult;
        int count = 0;
        boolean secondFlag = false;
        if (pageQueryReq.getRefundslist().contains(RefundStatus.WAIT_SECOND_AUDIT)) {
            secondFlag = true;
        }
        do {
            //获取待审核分页退票申请列表
            pageResult = loadRefundApplys(pageQueryReq);
            LOG.info("Total {} size will be checked in auto first audit", pageResult.getTotalCount());
            List<RefundApplyDto> refundApplyList = pageResult.getData();
            List<RefundApplyDto> refunApplyUpdateList = new ArrayList<>();
            if (secondFlag) {
                for (RefundApplyDto refundApply : refundApplyList) {
                    //检查是否可执行自动审核及保存审核相关结果
                    doScheduleTask(refundApply);
                }
            }else{
                for (RefundApplyDto refundApply : refundApplyList) {
                    //检查是否可执行自动审核及保存审核相关结果
                    doScheduleTask(refundApply);

                    refunApplyUpdateList.add(refundApply);

                    if (++count % batchSize == 0) {
                        LOG.debug("Batch updating record");
                        refundUpdateOperation.updateRefundApplyDtos(refunApplyUpdateList);
                        refundUpdateOperation.saveRefundAudits(refunApplyUpdateList);
                        refunApplyUpdateList.clear();
                    }
                }
                if (!CollectionUtils.isEmpty(refunApplyUpdateList)) {
                    refundUpdateOperation.updateRefundApplyDtos(refunApplyUpdateList);
                    refundUpdateOperation.saveRefundAudits(refunApplyUpdateList);
                    refunApplyUpdateList.clear();
                }
            }

            if (pageResult.isHasNextPage()) {
                pageQueryReq = (BasePageQueryReq) pageQueryReq.createNextPage();
            }
        } while (pageResult.isHasNextPage());
    }

    protected PaginationResult<RefundApplyDto> loadRefundApplys(BasePageQueryReq pageQueryReq) {
        PaginationResult<RefundApplyDto> result = refundQueryOperation.loadByPage(pageQueryReq);
        return result;
    }

    abstract void doScheduleTask(RefundApplyDto refundApply);

    abstract BasePageQueryReq buildQueryReq();

}
